{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "00_pytorch_fundamentals_exercises.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# 00. PyTorch Fundamentals Exercises\n",
        "\n",
        "### 1. Documentation reading \n",
        "\n",
        "A big part of deep learning (and learning to code in general) is getting familiar with the documentation of a certain framework you're using. We'll be using the PyTorch documentation a lot throughout the rest of this course. So I'd recommend spending 10-minutes reading the following (it's okay if you don't get some things for now, the focus is not yet full understanding, it's awareness):\n",
        "  * The documentation on [`torch.Tensor`](https://pytorch.org/docs/stable/tensors.html#torch-tensor).\n",
        "  * The documentation on [`torch.cuda`](https://pytorch.org/docs/master/notes/cuda.html#cuda-semantics).\n",
        "\n"
      ],
      "metadata": {
        "id": "AzDBM_v4iMe7"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# No code solution (reading)"
      ],
      "metadata": {
        "id": "bGD0oD8Kizak"
      },
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 2. Create a random tensor with shape `(7, 7)`.\n"
      ],
      "metadata": {
        "id": "__iXqqz-ioUJ"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Import torch\n",
        "\n",
        "\n",
        "# Create random tensor\n"
      ],
      "metadata": {
        "id": "6pUq9Dc8i2L7"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 3. Perform a matrix multiplication on the tensor from 2 with another random tensor with shape `(1, 7)` (hint: you may have to transpose the second tensor)."
      ],
      "metadata": {
        "id": "9-XxvRLfiqkR"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Create another random tensor\n",
        "\n",
        "# Perform matrix multiplication \n"
      ],
      "metadata": {
        "id": "NcLqR0Sbi_vT"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 4. Set the random seed to `0` and do 2 & 3 over again.\n",
        "\n",
        "The output should be:\n",
        "```\n",
        "(tensor([[1.8542],\n",
        "         [1.9611],\n",
        "         [2.2884],\n",
        "         [3.0481],\n",
        "         [1.7067],\n",
        "         [2.5290],\n",
        "         [1.7989]]), torch.Size([7, 1]))\n",
        "```"
      ],
      "metadata": {
        "id": "eiutdKUFiryU"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Set manual seed\n",
        "\n",
        "\n",
        "# Create two random tensors\n",
        "\n",
        "\n",
        "# Matrix multiply tensors\n"
      ],
      "metadata": {
        "id": "D-lOWI_1jRMm"
      },
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 5. Speaking of random seeds, we saw how to set it with `torch.manual_seed()` but is there a GPU equivalent? (hint: you'll need to look into the documentation for `torch.cuda` for this one)\n",
        "  * If there is, set the GPU random seed to `1234`."
      ],
      "metadata": {
        "id": "ezY6ks9Cis37"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Set random seed on the GPU\n"
      ],
      "metadata": {
        "id": "_LKWcfSTjp00"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "\n",
        "### 6. Create two random tensors of shape `(2, 3)` and send them both to the GPU (you'll need access to a GPU for this). Set `torch.manual_seed(1234)` when creating the tensors (this doesn't have to be the GPU random seed). The output should be something like:\n",
        "\n",
        "```\n",
        "Device: cuda\n",
        "(tensor([[0.0290, 0.4019, 0.2598],\n",
        "         [0.3666, 0.0583, 0.7006]], device='cuda:0'),\n",
        " tensor([[0.0518, 0.4681, 0.6738],\n",
        "         [0.3315, 0.7837, 0.5631]], device='cuda:0'))\n",
        "```"
      ],
      "metadata": {
        "id": "Ir9qSaj6it4n"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Set random seed\n",
        "\n",
        "\n",
        "# Check for access to GPU\n",
        "\n",
        "# Create two random tensors on GPU\n"
      ],
      "metadata": {
        "id": "azXExiFZj5nm"
      },
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "\n",
        "### 7. Perform a matrix multiplication on the tensors you created in 6 (again, you may have to adjust the shapes of one of the tensors).\n",
        "\n",
        "The output should look like:\n",
        "```\n",
        "(tensor([[0.3647, 0.4709],\n",
        "         [0.5184, 0.5617]], device='cuda:0'), torch.Size([2, 2]))\n",
        "```"
      ],
      "metadata": {
        "id": "5TlAxeiSiu1y"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Perform matmul on tensor_A and tensor_B\n"
      ],
      "metadata": {
        "id": "fAeG7ox0lHEO"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 8. Find the maximum and minimum values of the output of 7."
      ],
      "metadata": {
        "id": "G7qfa5CSivwg"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Find max\n",
        "\n",
        "# Find min\n"
      ],
      "metadata": {
        "id": "Fu8_3mZpllOd"
      },
      "execution_count": 8,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### 9. Find the maximum and minimum index values of the output of 7."
      ],
      "metadata": {
        "id": "wrTj5FgNiw47"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Find arg max\n",
        "\n",
        "\n",
        "# Find arg min\n"
      ],
      "metadata": {
        "id": "CCEKt4K2lsfQ"
      },
      "execution_count": 9,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "\n",
        "### 10. Make a random tensor with shape `(1, 1, 1, 10)` and then create a new tensor with all the `1` dimensions removed to be left with a tensor of shape `(10)`. Set the seed to `7` when you create it and print out the first tensor and it's shape as well as the second tensor and it's shape.\n",
        "\n",
        "The output should look like:\n",
        "\n",
        "```\n",
        "tensor([[[[0.5349, 0.1988, 0.6592, 0.6569, 0.2328, 0.4251, 0.2071, 0.6297,\n",
        "           0.3653, 0.8513]]]]) torch.Size([1, 1, 1, 10])\n",
        "tensor([0.5349, 0.1988, 0.6592, 0.6569, 0.2328, 0.4251, 0.2071, 0.6297, 0.3653,\n",
        "        0.8513]) torch.Size([10])\n",
        "```"
      ],
      "metadata": {
        "id": "hmeybz4uixy7"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Set seed\n",
        "\n",
        "\n",
        "# Create random tensor\n",
        "\n",
        "\n",
        "# Remove single dimensions\n",
        "\n",
        "\n",
        "# Print out tensors and their shapes\n"
      ],
      "metadata": {
        "id": "TQ9zbRzVl1jV"
      },
      "execution_count": 10,
      "outputs": []
    }
  ]
}